package com.szlizarrrr.demo.optional;


import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

import javax.transaction.Transactional;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import lombok.extern.slf4j.Slf4j;

@EnableAsync
@SpringBootApplication
@EnableJpaAuditing
@RestController
@Slf4j
public class OptionalDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(OptionalDemoApplication.class, args);
	}
	
	@Autowired
	CustomerRepository customerRepository;
	
	@GetMapping("/customers")
	public List<Customer> getCustomerList() {
		return customerRepository.findAll();
	}
	
	@PostMapping("/customers")
	@Transactional
	public Customer registCustomer(@Valid Customer customer) {
		customer.setFirstname(customer.getFirstname());
		customer.setLastname(customer.getLastname());
		return customerRepository.save(customer);
	}
	
	@GetMapping("/customers/{id}")
	public Optional<Customer> getOneCustomer(@PathVariable("id") Long id) {
		return customerRepository.findById(id);
	}
	
	@GetMapping("/customerl")
	@Transactional
	public void getStreamCustomer() throws Exception {
		customerRepository.streamAllCustomers().forEach(customer -> log.info(customer.id.toString()));
		CompletableFuture<Void> future = customerRepository.readAllBy().thenAccept(customers -> {
			customers.forEach(customer -> log.info(customer.getFirstname()));
			log.info("Completed!");
		});
		
		while(!future.isDone()) {
			log.info("Waiting for the CompletableFuture to finish...");
			TimeUnit.MILLISECONDS.sleep(500);
		}
		future.get();
		log.info("Done!");
	}
	
}
